package com.ywl.designpattern.singleton.type5;

/**
 * @author yuwl
 * @description 单例设计模式-懒汉式（同步代码块+双重检查+volatile, 解决线程安全问题，高效可用，推荐）
 * @since 2024-02-29 10:07
 */
public class Singleton {

    /**
     * 这种模式需要使用volatile关键字来确保singleton字段的可见性。如果不使用volatile关键字，其他线程可能会看到一个半初始化的Singleton实例。
     */
    private static volatile Singleton singleton;

    private Singleton() {}

    /**
     * 同步代码块，双重检查解决线程安全问题
     * 这种模式的优点是，只有在第一次调用getInstance方法时，才需要获取锁。这就减少了锁的开销，提高了性能。
     * 这种模式也有一个缺点。那就是，由于Java内存模型的复杂性，这种模式需要使用volatile关键字来确保singleton字段的可见性。
     * 如果不使用volatile关键字，其他线程可能会看到一个半初始化的Singleton实例。这就可能导致错误。
     * @return
     */
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                Singleton instance = Singleton.getInstance();
                System.out.println(Thread.currentThread().getName() + ", instance = " + instance);
                System.out.println(Thread.currentThread().getName() + ", instance.hashCode() = " + instance.hashCode());
            }).start();
        }
    }
}
